package gui.std;

import gui.std.games.battleships.GBSGame;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;

import util.Constants;
import app.Client;
import app.Request;
import app.User;

@SuppressWarnings("serial")
public class GClient extends JFrame {
	
	public GClient(String server, User user) {
		this.user = user;
		client = new Client(server, user);
		bsVector = new Vector<GBSGame>();
		initialize();
		updateUList();		
	}
	
	@SuppressWarnings("unchecked")
	private void initialize() {		
		setSize(WIDTH, HEIGHT);
		setTitle("Client App");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		
		Container c = getContentPane();
		c.setLayout(new BorderLayout());
		
		info = new JPanel(new BorderLayout());
		paneList = new JPanel();
		cp = new GChatPanel(client);
		cp.append("Logged in as "+user.getNick()+" at "+client.getLoginDate()+".\n");
		cp.showLog();
		
		//Message Manager
		Thread t = new Thread() {
			public void run() {
				try {
					while (true) {
						Request r = (Request)client.chatReceive();
						
						switch (r.getType()) {
							//ChatMessage
							case Request.CHAT_MSG: 
								cp.append((String)r.getMsg());
								break;
						
							//Game request
							case Request.GAME_REQUEST:
								int opt = JOptionPane.showConfirmDialog(_this, r.getSource().getNick() + 
																		" is asking for a game with u. Do u accept?", 
																		"Request Window", JOptionPane.YES_NO_OPTION);
								if (opt == JOptionPane.YES_OPTION) {
									r.setTarget(user);
								
									//creating new game
									GBSGame bs = new GBSGame(client, r.getSource());
									bs.setID((Long)r.getMsg());
									bs.setLocationRelativeTo(_this);
									bs.setVisible(true);
									
									//adding to bs Container
									bsVector.add(bs);
								}
								else
									r.getTarget().setId(-1);
							
								r.setType(Request.GAME_RESPONSE);
								client.chatSend(r);
								break;
						
							//Game response
							case Request.GAME_RESPONSE:
								if (r.getTarget().getId() == -1) {
									JOptionPane.showMessageDialog(_this, r.getTarget().getNick() + 
															  	" has rejected your game request.", 
															  	"Request Window", JOptionPane.INFORMATION_MESSAGE);
								}
								else {
									//creating new game
									GBSGame bs = new GBSGame(client, r.getTarget());
									bs.setID((Long)r.getMsg());
									bs.setLocationRelativeTo(_this);
									bs.setVisible(true);
									
									//adding to bs Container
									bsVector.add(bs);
								}
								break;
							
							//game is ready
							case Request.DONE:
								//looking for game
								int ind = 0;
								while (bsVector.get(ind).getId() != r.getTarget().getId())
									ind++;
								
								bsVector.get(ind).setReady();
								break;
							
							//time to attack
							case Request.ATTACK:
								//looking for game
								ind = 0;
								while (bsVector.get(ind).getId() != r.getTarget().getId())
									ind++;
								
								bsVector.get(ind).attack();
								break;
								
							case Request.POS_REQUEST:
								ind = 0;
								while (bsVector.get(ind).getId() != r.getTarget().getId())
									ind++;
								
								bsVector.get(ind).showRequest((Point)r.getMsg());
								break;
								
							case Request.POS_RESPONSE:
								ind = 0;
								while (bsVector.get(ind).getId() != r.getTarget().getId())
									ind++;
								
								bsVector.get(ind).showResponse((Boolean)r.getMsg());
								break;
								
						}
						
						sleep(Constants.CONN_CONTROL_TIME);
					}
				}
				catch (Exception e){e.printStackTrace();}
			}
		};
		
		cp.setUpdateAction(t);
		cp.startUpdating();
		
		uList = new GUserList();
		uList.setUser(user);
		uList.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JButton b = (JButton)e.getSource();
				int opt = JOptionPane.showConfirmDialog(_this, "Ask for a game with "+ b.getActionCommand().trim() +"?", 
														"Request Window", JOptionPane.YES_NO_OPTION);
				if (opt == JOptionPane.YES_OPTION) {
					User target = new User(e.getActionCommand().trim(), Integer.parseInt(b.getName()));
					try {
						Request r = new Request(user, target);
						r.setType(Request.GAME_REQUEST);
						client.chatSend(r);
					}
					catch (IOException e1) {e1.printStackTrace();}
				}
			}
		});
		
		try {
			uList.update((Vector<User>)client.loginReceive());
		}
		catch (Exception e){}
		paneList.add(uList);

		hSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, cp, info);
		hSplit.setDividerLocation(430);
		
		info.add(new GUserInfo(user), BorderLayout.NORTH);
		info.add(new JScrollPane(paneList));
		c.add(hSplit);
		
		setVisible(true);
	}
	
	private void updateUList() {
		new Thread() {
			@SuppressWarnings("unchecked")
			public void run() {
				while (true) {
					try {
						uList.update((Vector<User>)client.loginReceive());
						sleep(Constants.CONN_CONTROL_TIME);
					}
					catch (Exception e) {}
				}
			}
		}.start();
	}
	
	private static final int WIDTH = 780;
	private static final int HEIGHT = 480;
	
	private Vector<GBSGame> bsVector;
	
	private User user;
	private Client client;
	private JPanel info;
	private JPanel paneList;
	private GChatPanel cp;
	private GUserList uList;
	private JSplitPane hSplit;
	private JFrame _this = this;
}